-- {-# LANGUAGE TemplateHaskell #-}
module Main where

import Numeric
import Types
import Strategy
import Fetcher
import ResultProcess
import Database.HDBC
import Data.Time.LocalTime
import Data.Time.Calendar
import Data.Maybe
-- import System.Log.Logger.TH (deriveLoggers)
import qualified System.Log.Logger as HSL
import System.Log.Handler.Simple
import System.Log.Formatter
import System.Log.Handler

{-
$(deriveLoggers "HSL" [HSL.INFO]) -}

data IConnection m => CoreRunner m = CoreRunner {
        crEvaluator     :: BaseEvaluator,
        crFetcher       :: BaseFetcher m
       } 

instance IConnection m => Fetcher (CoreRunner m) where
        fGetHigh        = fGetHigh . crFetcher
        fGetLow         = fGetLow . crFetcher
        fGetBar         = fGetBar . crFetcher

instance IConnection m => StrategyEvaluator (CoreRunner m) where
        evalOrders r bar orders = (CoreRunner { crEvaluator = e, crFetcher = crFetcher r }, pnl)
                where (e, pnl) = evalOrders (crEvaluator r) bar orders

instance IConnection m => BarModifier (CoreRunner m) where
       getAskBar = getAskBar . crEvaluator
       getBidBar = getBidBar . crEvaluator

data BracketParameters = Bracket {
        bpH     :: Double,
        bpL     :: Double,
        bpSl    :: Double,
        bpV     :: Double
        }

convertToOrders bp openPrice = [buy, sell]
        where   buy     = BuyOrder {orderVolume = bpV bp, orderPrice = lowPrice, orderStopLoss = lowPrice - (bpSl bp), orderTakeProfit = highPrice }
                sell    = SellOrder {orderVolume = bpV bp, orderPrice = highPrice, orderStopLoss = highPrice + (bpSl bp), orderTakeProfit = lowPrice }
                highPrice = openPrice + (bpH bp)
                lowPrice  = openPrice - (bpL bp)
         

data SimpleStrategy = SS

instance Strategy SimpleStrategy where
        stProcess m si = (m, convertToOrders bp (siOpenPrice si))
                where   bp = Bracket {bpH = (siDayHigh si), bpL = (siDayLow si), bpSl = 0.0050, bpV = 1.0 }

instance IConnection m => StrategyRunner (CoreRunner m) 


prepareLogger fName = do
        s <- fileHandler fName HSL.DEBUG
        HSL.updateGlobalLogger HSL.rootLoggerName (HSL.addHandler s)
        return s

main :: IO ()
main = do
       logger <- prepareLogger "backtest.log"
       HSL.infoM "Backtester" "Open connections..."
       c <- defaultConnection
       let bfetcher = BaseFetcher c
       let crunner = CoreRunner (BaseEvaluator 0.0002) bfetcher
       let fd = LocalTime (fromGregorian 2010 01 04) (TimeOfDay 0 0 0)
       let td = LocalTime (fromGregorian 2010 12 01) (TimeOfDay 0 0 0)
       putStrLn $ "Running from "++(show fd)++" to "++(show td)
       (s, result) <- runStrategy crunner SS 1 fd td
       let finalResult = rprocess result :: SimpleResult
       putStrLn $ "Final result = " ++ (show finalResult)
       close logger

